﻿using AutoMapper;
using HomeCloudStorageSystem.Dtos;
//using HomeCloudStorageSystem.Models;
using HomeCloudStorageSystem.Services;
using Microsoft.AspNetCore.Authorization;
//using Microsoft.AspNetCore.Http;
//using Microsoft.AspNetCore.Http.Metadata;
using Microsoft.AspNetCore.Mvc;
//using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Caching.Memory;
//using Microsoft.IdentityModel.JsonWebTokens;
using Microsoft.IdentityModel.Tokens;
using Newtonsoft.Json;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;

namespace HomeCloudStorageSystem.Controllers
{
    /// <summary>
    /// 用户校验接口
    /// </summary>
    [Route("api/[controller]")]
    [ApiController]
    public class AuthController : ControllerBase
    {
        private readonly IMapper _mapper;
        public readonly IMemoryCache _memoryCache;
        private readonly IConfiguration _configuration;
        private readonly IUserRepository _userRepository;
        public AuthController(IMapper mapper, IMemoryCache memoryCache, IConfiguration configuration, IUserRepository userRepository)
        {
            _mapper = mapper;
            _memoryCache = memoryCache;
            _configuration = configuration;
            _userRepository = userRepository;
        }
        /// <summary>
        /// 用户登录接口
        /// </summary>
        /// <param name="loginDto">用户登录信息</param>
        /// <returns>登录成功信息</returns>
        [AllowAnonymous]
        [HttpPost("login")]
        public IActionResult Login([FromBody] LoginDto loginDto)
        {
            if (loginDto.UserName == null || loginDto.Password == null)
            {
                return BadRequest("账号或密码错误");
            }
            // 1、验证用户名和密码
            var userFromRepository = _userRepository.GetUserByUserName(loginDto.UserName);
            if (userFromRepository == null)
            {
                return Unauthorized("登录账号错误");
            }
            if (!string.IsNullOrEmpty(userFromRepository.Password))
            {
                if (userFromRepository.Password.Trim() != loginDto.Password)
                {
                    return Unauthorized("登录密码错误");
                }
            }
            else
            {
                return Unauthorized("该用户还未注册");
            }

            // 2、创建 jwt   jwt = 用户ID
            // header 定义了 token的编码算法
            var signinAlgorithm = SecurityAlgorithms.HmacSha256;
            // payload 主体数据，可自定义

            // 在 claims中注明用户的身份和权限
            var claims = new[]
            {
                // jwt中 id 的专有名词：sub
                new Claim(Microsoft.IdentityModel.JsonWebTokens.JwtRegisteredClaimNames.Sub,loginDto.UserName)
            };
            // signiure 数字签名（私钥）,放置在配置文件中。 密钥的长度至少为16个字符，不然会报错
            var secretByte = Encoding.UTF8.GetBytes(_configuration["Authentication:SecretKey"]);
            // 使用非对称加密算法进行加密
            var signingKey = new SymmetricSecurityKey(secretByte);
            // 数字签名
            var signingCreadentials = new SigningCredentials(signingKey, signinAlgorithm);

            //创建 token
            var token = new JwtSecurityToken(
                issuer: _configuration["Authentication:Issuer"],
                audience: _configuration["Authentication:Audience"],
                claims,
                notBefore: DateTime.UtcNow,
                expires: DateTime.UtcNow.AddDays(1), //AddSeconds(30),//.AddDays(1),
                signingCreadentials
            );

            var tokenstr = new JwtSecurityTokenHandler().WriteToken(token);

            //var user_key = userFromRepository.Id.ToString() + "_Token";

            // 缓存指令，指令有效时间为两小时
            var cacheEntryOptions = new MemoryCacheEntryOptions().SetSlidingExpiration(TimeSpan.FromSeconds(10));
            _memoryCache.Set("user_key", JsonConvert.SerializeObject(tokenstr), cacheEntryOptions);

            // 3、返回 200 ok 、jwt
            return Ok(tokenstr);
        }

        [HttpPost("register")]
        public IActionResult Register(IFormFile file, [FromForm] string userName, [FromForm] string password, [FromForm] string phone)
        {
            if (file == null || userName == "" || password == "" || phone == "")
            {
                return BadRequest("请求错误");
            }
            if (_userRepository.GetUserByUserName(userName) != null)
            {
                return Conflict("此用户名已被使用");
            }
            // http://localhost:5198/api/Avatars/
            var avatarsUrl = HttpContext.Request.Scheme + @"://" + HttpContext.Request.Headers.Host + @"/api/Avatars/";
            var message = _userRepository.AddUser(file, userName, password, phone, avatarsUrl);
            if (message == "注册失败")
            {
                return BadRequest(message);
            }
            return Ok(message);
        }
    }
}
